home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------------
-
- Module name: structure content drawer
-
- Author: Toby Howard
-
- Function: This module implements the structure content drawer.
-
- Dependencies:
-
- External function list:
-
- Internal function list:
-
- Hashtables used: "structureid", "label".
-
- Modification history : (Version), (Date), (Name), (Description).
-
- 1.0, ????, Toby Howard, First version.
-
- 1.1, 15th July 1988, Steve Larkin, Modified to work with VAX Phigs.
-
- 2.0, 27th August 1991, Gareth Williams, Translated to C.
-
- 3.0, June 1992, Gareth Williams, Converted to ISO PHIGS C.
-
- ----------------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <math.h>
- #include <phigs.h>
- #include "ptk.h"
-
- #define OFFSET 0.025
-
- static Pint stctwsid, stfirstel, stlastel, stctfont;
- static Pfloat elemheight, elemtypewidth, elemptrwidth;
- static Ppoint topleftbox;
- static Pint no_els;
- static Pint first_element;
- static Ppoint tp;
-
- /*--------------------------------------------------------------------------*/
-
- static void setscaling()
- /* computes the transformation to scale the picture
- ** into [0,1], and inserts a global transformation at the
- ** start of the picture.
- */
- {
- Pmatrix3 globaltran;
- Pint err, el;
- Pfloat depth;
- Ppoint3 shift, scale;
-
- if ((stlastel - stfirstel) >= 9)
- {
- depth = (stlastel - stfirstel + 2) * 0.1;
- shift = ptk_point3(0.0, -1.0, 0.0);
- ptk_shift3(&shift, PTYPE_REPLACE, globaltran);
- scale = ptk_point3(1.0/depth, 1.0/depth, 1.0);
- ptk_scale3(&scale, PTYPE_POSTCONCAT, globaltran);
- shift = ptk_point3(0.0, 1.0, 0.0);
- ptk_shift3(&shift, PTYPE_POSTCONCAT, globaltran);
- }
- else
- ptk_unitmatrix3(globaltran);
- /* Squeeze in a global transformation at the top of the structure */
- pinq_elem_ptr(&err, &el);
- pset_elem_ptr(first_element);
- pset_elem_ptr_label(ptk_stringtoint("label", "globaltran"));
- pset_global_tran3(globaltran);
- pset_elem_ptr(el + 1);
- } /* setscaling */
-
- /*--------------------------------------------------------------------------*/
-
- static void initialise()
- {
- Pfloat charht;
- Ptext_align align;
- Ppoint elembox;
-
- elemheight = 0.1;
- elemtypewidth = 0.7;
- elemptrwidth = 0.2;
- topleftbox = ptk_point(0.0, 1.0);
-
- align.hor = PHOR_NORM;
- align.vert = PVERT_HALF;
- pset_text_align(&align);
- elembox = ptk_point(elemtypewidth - OFFSET - 0.01, elemheight);
- ptk_computecharheight(stctwsid, "set_annotation_text_character_up_vector",
- &elembox, stctfont, &charht);
- pset_char_ht(charht);
- pset_text_font(stctfont);
- } /* initialise */
-
- /*--------------------------------------------------------------------------*/
-
- static void elemtypebox(C(Pelem_type) eltype, C(Pint) elemnum)
- PreANSI(Pelem_type eltype)
- PreANSI(Pint elemnum)
- /*
- ** Assumes there is no local tran in effect
- */
- {
- Ppoint pts[4];
- char str[50];
- Pint totlen;
- Ppoint_list sets;
-
- pts[0] = topleftbox;
- pts[1] = ptk_point(pts[0].x + elemtypewidth, pts[0].y);
- pts[2] = ptk_point(pts[1].x, pts[0].y - elemheight);
- pts[3] = ptk_point(pts[0].x, pts[2].y);
- sets.num_points = 4;
- sets.points = pts;
- ptk_fillareaset(1, &sets);
- ptk_getelemtypename(eltype, 50, str, &totlen);
- tp = ptk_point(topleftbox.x + OFFSET, topleftbox.y - 0.05);
- ptext(&tp, str);
- sprintf(str, "%d\0", elemnum);
- tp = ptk_point(topleftbox.x + elemtypewidth + OFFSET,
- topleftbox.y - 0.05);
- ptext(&tp, str);
- } /* elemtypebox */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_structcontent(C(Pint) wsid, C(Pint) stid, C(Pint) firstel,
- C(Pint) lastel, C(Pint) elemptr, C(Pint) font,
- C(Pint *) error)
- PreANSI(Pint wsid)
- PreANSI(Pint stid)
- PreANSI(Pint firstel)
- PreANSI(Pint lastel)
- PreANSI(Pint elemptr)
- PreANSI(Pint font)
- PreANSI(Pint *error)
- /*
- ** \parambegin
- ** \param{Pint}{wsid}{workstation identifier}{IN}
- ** \param{Pint}{stid}{structure identifier}{IN}
- ** \param{Pint}{firstel}{first element in range}{IN}
- ** \param{Pint}{lastel}{last element in range}{IN}
- ** \param{Pint}{elemptr}{element pointer}{IN}
- ** \param{Pint}{font}{text font}{IN}
- ** \param{Pint *}{error}{error code}{OUT}
- ** \paramend
- ** \blurb{This function inserts a diagram of the contents of the structure
- ** {\tt stid} in the currently open structure at the current editing
- ** position. The diagram consists of a table of elements represented
- ** by rectangles and labelled with element type and number. The table
- ** has a heading with the format:
- ** {\tt "structure N "name" (M elements)"}
- ** where N is the structure identifier, name is the structure name
- ** extracted from the "structureid" hashtable and M is the total
- ** number of elements in the structure. The error code = 1 if there
- ** is no open structure and = 2 if {\tt stid} doesn't exist.
- ** This function requires hashtable "label".}
- */
- {
- Popen_struct_status structst;
- Pint i, err, curname, lenstr, elptr;
- Pelem_type etype;
- char str[80], name[30];
- Ppoint3 arrowcentre;
- Ppoint3 arrowshift;
- Pmatrix3 mat;
-
- stctwsid = wsid;
- stfirstel = firstel;
- stlastel = lastel;
- stctfont = font;
- *error = 0;
-
- pinq_open_struct(error, &structst, &curname);
- if (structst == PSTRUCT_NONE)
- {
- *error = 1;
- fprintf(stderr, "ptk_structcontent: needs a structure open\n");
- return;
- }
-
- if (!ptk_structexists(stid))
- {
- *error = 2;
- fprintf(stderr, "ptk_structcontent: structure %d doesn't exist\n", stid);
- return;
- }
-
- ptk_seteditmode(PEDIT_INSERT);
- /* validate the requested element range */
- no_els = ptk_elemcount(stid);
- if (stfirstel <= 0)
- stfirstel = 1;
- if ((stlastel > no_els) || (stlastel == 0))
- stlastel = no_els;
- if (stlastel < stfirstel)
- stlastel = stfirstel;
-
- pinq_elem_ptr(&err, &first_element);
- plabel(ptk_stringtoint("label", "globaltran"));
- plabel(ptk_stringtoint("label", "elementpointer"));
- plabel(ptk_stringtoint("label", "start-structcontent"));
- ptk_unitmatrix3(mat);
- pset_local_tran3(mat, PTYPE_REPLACE);
- initialise();
-
- /* heading */
- if (ptk_hashtableused("structureid"))
- {
- ptk_inttostring("structureid", stid, 30, name, &lenstr);
- if (lenstr != 0)
- sprintf(str, "structure %d \"%s\" (%d elements)\0", stid,
- name, no_els);
- else
- sprintf(str, "structure %d (%d elements)\0", stid,
- no_els);
- }
- tp = ptk_point(topleftbox.x + OFFSET, topleftbox.y - 0.05);
- ptext(&tp, str);
- topleftbox.y -= elemheight;
- /* elements */
- for (i = stfirstel; i <= stlastel; i++)
- {
- ptk_inqelemtype(stid, i, error, &etype);
- if (*error != 0)
- etype = PELEM_NIL;
- pset_pick_id(i); /* pick identifier = element pointer */
- elemtypebox(etype, i);
- if (i == elemptr)
- {
- pinq_elem_ptr(&err, &elptr);
- pset_elem_ptr(0);
- pset_elem_ptr_label(ptk_stringtoint("label", "elementpointer"));
- arrowshift = ptk_point3(0.9, topleftbox.y - 0.05, 0.0);
- ptk_shift3(&arrowshift, PTYPE_REPLACE, mat);
- pset_local_tran3(mat, PTYPE_REPLACE);
- /* insert arrow */
- arrowcentre = ptk_point3(0.0, 0.0, 0.0);
- ptk_arrow(0.1, 0.075, &arrowcentre, 90.0);
- /* jump back */
- pset_elem_ptr(elptr + 2);
- }
- topleftbox.y -= elemheight;
- }
-
- setscaling();
- plabel(ptk_stringtoint("label", "end-structcontent"));
- ptk_unseteditmode();
- } /* ptk_structcontent */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_inqstructcontentrange(C(Pint) contentstid, C(Pint *) firstel,
- C(Pint *) lastel, C(Pint *) err)
- PreANSI(Pint contentstid)
- PreANSI(Pint *firstel)
- PreANSI(Pint *lastel)
- PreANSI(Pint *err)
- /*
- ** \parambegin
- ** \param{Pint}{contentstid}{content structure identifier}{IN}
- ** \param{Pint *}{firstel}{element pointer}{OUT}
- ** \param{Pint *}{lastel}{element pointer}{OUT}
- ** \param{Pint *}{err}{error indicator}{OUT}
- ** \paramend
- ** \blurb{This function may be used to obtain the element range which appears
- ** in the structure content diagram. The error code = 1 if {\tt contentstid}
- ** is not a structure content diagram.}
- */
- {
- Pint elptr, lstnum;
- ptkselcontent elcont;
- Psearch_status stat;
- Pstore store;
- Pelem_type eltype;
-
- *err = 0;
- ptk_openstruct(contentstid);
- pset_elem_ptr(0);
- if (ptk_findlabel(ptk_stringtoint("label", "start-structcontent"), &elptr))
- {
- pset_elem_ptr(0);
- pset_elem_ptr_label(ptk_stringtoint("label", "start-structcontent"));
- eltype = PELEM_TEXT;
- ptk_findelemtype(&eltype, 1, PDIR_FORWARD, &stat, &elptr, &lstnum);
- pset_elem_ptr(elptr + 1);
- ptk_findelemtype(&eltype, 1, PDIR_FORWARD, &stat, &elptr, &lstnum);
- pset_elem_ptr(elptr + 1);
- ptk_findelemtype(&eltype, 1, PDIR_FORWARD, &stat, &elptr, &lstnum);
- pcreate_store(err, &store);
- if (stat == PSEARCH_STATUS_SUCCESS)
- {
- ptk_inqelemtypesizecontent(contentstid, elptr, store, err, &elcont);
- *firstel = atoi(elcont.eldata->text.char_string);
- }
- pset_elem_ptr_label(ptk_stringtoint("label", "end-structcontent"));
- ptk_findelemtype(&eltype, 1, PDIR_BACKWARD, &stat, &elptr, &lstnum);
- if (stat == PSEARCH_STATUS_SUCCESS)
- {
- ptk_inqelemtypesizecontent(contentstid, elptr, store, err, &elcont);
- *lastel = atoi(elcont.eldata->text.char_string);
- }
- ptk_delstore(store);
- }
- else
- *err = 1;
- ptk_closestruct();
- } /* ptk_inqstructcontentrange */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_setstructcontentelemptr(C(Pint) contentstid, C(Pint) elemptr)
- PreANSI(Pint contentstid)
- PreANSI(Pint elemptr)
- /*
- ** \parambegin
- ** \param{Pint}{contentstid}{content structure identifier}{IN}
- ** \param{Pint}{elemptr}{element pointer}{IN}
- ** \paramend
- ** \blurb{This function draws an arrow pointing the element {\tt elemptr}
- ** in the structure content diagram.}
- */
- {
- Pint range1, range2, err;
- Ppoint3 arrowcentre;
- Ppoint3 arrowshift;
- Pmatrix3 mat;
-
- /* find element range */
- ptk_inqstructcontentrange(contentstid, &range1, &range2, &err);
- if (err == 0)
- {
- if ((elemptr >= range1) && (elemptr <= range2))
- {
- ptk_openstruct(contentstid);
- pset_elem_ptr(0);
- pdel_elems_labels(ptk_stringtoint("label", "elementpointer"),
- ptk_stringtoint("label", "start-structcontent"));
- arrowshift = ptk_point3(0.9, 0.0, 0.0);
- arrowshift.y = 0.95 + (-0.1 * (Pfloat)(elemptr - range1 + 1));
- ptk_shift3(&arrowshift, PTYPE_REPLACE, mat);
- pset_pick_id(elemptr);
- pset_local_tran3(mat, PTYPE_REPLACE);
- /* insert arrow */
- arrowcentre = ptk_point3(0.0, 0.0, 0.0);
- ptk_arrow(0.1, 0.075, &arrowcentre, 90.0);
- ptk_closestruct();
- }
- }
- } /* ptk_setstructcontentelemptr */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_inqstructcontentelemptr(C(Pint) contentstid,
- C(Pint *) elemptr, C(Pint *) err)
- PreANSI(Pint contentstid)
- PreANSI(Pint *elemptr)
- PreANSI(Pint *err)
- /*
- ** \parambegin
- ** \param{Pint}{contentstid}{content structure identifier}{IN}
- ** \param{Pint *}{elemptr}{element pointer}{OUT}
- ** \param{Pint *}{err}{error indicator}{OUT}
- ** \paramend
- ** \blurb{This function may be used to obtain the element number pointed
- ** to by the element arrow in the structure content diagram.
- ** The error code = 1 if {\tt contentstid} is not a
- ** structure content diagram.}
- */
- {
- Psearch_status stat;
- Pint elptr, lstnum;
- Pelem_type elemlist[2];
-
- *err = 0;
- ptk_openstruct(contentstid);
- pset_elem_ptr(0);
- if (ptk_findlabel(ptk_stringtoint("label", "elementpointer"), &elptr))
- {
- pset_elem_ptr_label(ptk_stringtoint("label", "elementpointer"));
- poffset_elem_ptr(1);
- elemlist[0] = PELEM_PICK_ID;
- elemlist[1] = PELEM_LABEL;
- ptk_findelemtype(elemlist, 2, PDIR_FORWARD, &stat, &elptr, &lstnum);
- if ((stat == PSEARCH_STATUS_SUCCESS) && (lstnum == 0))
- ptk_getpickid(contentstid, elptr, elemptr);
- }
- else
- *err = 1;
- ptk_closestruct();
- } /* ptk_inqstructcontentelemptr */
-
- /*--------------------------------------------------------------------------*/
-
- /* end of stct.c */
-